<?php

/**
 * @Author: Wang chunsheng  email:2192138785@qq.com
 * @Date:   2023-04-24 19:00:27
 * @Last Modified by:   Wang chunsheng  email:2192138785@qq.com
 * @Last Modified time: 2023-07-28 14:54:38
 */

namespace Common\Services;

use Common\Helpers\DebugHelper;
use Common\Libs\Jwt\Jwt;
use Common\Models\ApiAccessToken;
use Common\Models\AuthMemberAppid;
use Common\Models\Member;
use Common\Services\Sys\ProjectService;
use Hyperf\Stringable\Str;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class MemberService
{

    public static function getMemberByAppid($appid): array
    {
        $member_id = AuthMemberAppid::query()->where(['AppID' => $appid])->value('member_id');
        $member = Member::query()->where([
            'member_id' => $member_id
        ])->select('member_id', 'username', 'mobile', 'address', 'nickName', 'avatarUrl', 'gender', 'country', 'province', 'realname')->first()->toArray();

        $projects   = ProjectService::getProjectByMid($member_id);
        return [
            'member' => $member,
            'projects' => $projects
        ];
    }

    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public static function register($project_id,$username, $password, $member_code = '', $mobile = '', $smsCode = ''): array
    {
        /* 查看手机号是否重复 */
        if ($mobile) {
            $userinfo = Member::query()->where(
                'mobile' , $mobile
            )
                ->where(['<>', 'mobile', 0])->value('member_id');
            if (!empty($userinfo)) {
                return [
                    'code' => 0,
                    'message' => '手机号重复',
                    'data' => null
                ];
            }
        }

        /* 查看手机号是否重复 */
        $userinfo = Member::query()->where([
            'username' => $username
        ])->value('member_id');
        if (!empty($userinfo)) {
            return [
                'code' => 0,
                'message' => '用户名重复',
                'data' => null
            ];
        }

        $Member = new Member();
        $member_id = $Member->addInfo([
            'password_hash' => (new PasswordService())->makePasswordHash($password),
            'password_reset_token' => Str::random(20),
            'username' => $username,
            'project_id' => $project_id,
            'member_code' => $member_code,
            'mobile' => $mobile,
        ]);


        $member = Member::query()
            ->select('member_id', 'username', 'mobile', 'password_hash', 'status', 'address', 'nickName', 'avatarUrl', 'gender', 'country', 'province', 'realname')
            ->where(['member_id' => $member_id])
            ->first();

        DebugHelper::consoleWrite('注册add',[
            'member'=>$member_id
        ]);

        // 生成apitoken
        $apiToken = new ApiAccessToken();
        $config = JwtService::getConfig();
        $SecretKey = $config['SecretKey'];
        $jwtObject = Jwt::getInstance()
            ->setSecretKey($SecretKey) // 秘钥
            ->publish();

        $Iss = $config['Iss'];
        $Sub = $config['Sub'];
        $jwtObject->setAlg('HMACSHA256'); // 加密方式
        $jwtObject->setAud($username); // 用户
        $jwtObject->setExp(time() + 3600); // 过期时间
        $jwtObject->setIat(time()); // 发布时间
        $jwtObject->setIss($Iss); // 发行人
        $jwtObject->setJti(md5(time())); // jwt id 用于标识该jwt
        $jwtObject->setNbf(time() + 60 * 5); // 在此之前不可用
        $jwtObject->setSub($Sub); // 主题


        $refresh_token = Str::random(30);
        unset($member['password_hash']);
        // 自定义数据
        $dataInfo = [
            'member' => [
                'member_id' => $member['member_id'],
                'username' => $member['username'],
                'mobile' => $member['mobile'],
                'address' => $member['address'],
                'nickName' => $member['nickName'],
                'avatarUrl' => $member['avatarUrl'],
                'gender' => $member['gender'],
                'country' => $member['country'],
                'province' => $member['province'],
                'realname' => $member['realname'],
            ]
        ];
        $jwtObject->setData($dataInfo);

        // 最终生成的token
        $token = $jwtObject->__toString();

        $access_token = JwtService::encrypt_ecb($token);
        $apiToken->addInfo([
            'refresh_token' => $refresh_token,
            'access_token' => $access_token,
            'member_id' => $member_id
        ]);


        $project_id = ProjectService::getProjectByMid($member_id);

        return [
            'code' => 200,
            'message' => '注册成功',
            'data' => [
                $dataInfo,
                'project_id' => $project_id,
                'access_token' => $access_token,
                'refresh_token' => $refresh_token,
            ]
        ];
    }

    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public static function getMemberByCode($member_code, $project_id): bool|array
    {
        $member = Member::query()
            ->where(['member_code' => $member_code,'project_id'=>$project_id])
            ->with('getAccessToken')
            ->select('member_id', 'username', 'mobile', 'password_hash', 'status', 'address', 'nickName', 'avatarUrl', 'gender', 'country', 'province', 'realname')
            ->first();
        DebugHelper::consoleWrite('第三方绑定会员数据',[
            'member'=>$member
        ]);
        if (!empty($member)) {
            $username = $member['username'];
            $member_id = $member['member_id'];
            $config = JwtService::getConfig();
            $SecretKey = $config['SecretKey'];
            $jwtObject = Jwt::getInstance()
                ->setSecretKey($SecretKey) // 秘钥
                ->publish();

            $Iss = $config['Iss'];
            $Sub = $config['Sub'];
            $jwtObject->setAlg('HMACSHA256'); // 加密方式
            $jwtObject->setAud($username); // 用户
            $jwtObject->setExp(time() + 3600); // 过期时间
            $jwtObject->setIat(time()); // 发布时间
            $jwtObject->setIss($Iss); // 发行人
            $jwtObject->setJti(md5(time())); // jwt id 用于标识该jwt
            $jwtObject->setNbf(time() + 60 * 5); // 在此之前不可用
            $jwtObject->setSub($Sub); // 主题



            $tokens = $member->getAccessToken;
            $access_token = $tokens['access_token'];
            $refresh_token = $tokens['refresh_token'];
            $refresh_time = $tokens['refresh_time'];

            // 校验有效期
            if ($refresh_time < time()) {
                $refresh_token = Str::random(20);
                MemberService::editRefToken($member['member_id'], $refresh_token);
            }

            // 自定义数据
            $jwtObject->setData([
                'member' => [
                    'member_id' => $member['member_id'],
                    'username' => $member['username'],
                    'mobile' => $member['mobile'],
                    'address' => $member['address'],
                    'nickName' => $member['nickName'],
                    'avatarUrl' => $member['avatarUrl'],
                    'gender' => $member['gender'],
                    'country' => $member['country'],
                    'province' => $member['province'],
                    'realname' => $member['realname'],
                ]
            ]);

            // 最终生成的token
            $token = $jwtObject->__toString();
            $access_token = JwtService::encrypt_ecb($token);
            MemberService::editToken($member['member_id'], $access_token);

            return [
                'member' => [
                    'member_id' => $member['member_id'],
                    'username' => $member['username'],
                    'mobile' => $member['mobile'],
                    'address' => $member['address'],
                    'nickName' => $member['nickName'],
                    'avatarUrl' => $member['avatarUrl'],
                    'gender' => $member['gender'],
                    'country' => $member['country'],
                    'province' => $member['province'],
                    'realname' => $member['realname'],
                ],
                'project_id' => $project_id,
                'access_token' => $access_token,
                'refresh_token' => $refresh_token,
            ];
        } else {
            return false;
        }
    }

    public static function editToken($member_id, $access_token): bool
    {
        $Member = new ApiAccessToken();
        $data['access_token'] = $access_token;
        return $Member->updateInfo($data, ['member_id' => $member_id]);
    }


    public static function editRefToken($member_id, $refresh_token = ''): bool
    {
        $Member = new ApiAccessToken();
        $data['refresh_token'] = $refresh_token;
        $data['refresh_time'] = time() + 60 * 24 * 7;

        return $Member->updateInfo($data, ['member_id' => $member_id]);
    }
}
